{
    // Script will bail out after this many milliseconds.
    var timeout = 400;

    var start = new Date();
    start = start.getTime();

    var redirect = new RegExp("^http://www\\.amazon\\.(com|ca|co\\.jp|de|fr|co\\.uk)/(exec/obidos|o)/redirect", "i");
    var asin     = new RegExp("^http://www\\.amazon\\.(com|ca|co\\.jp|de|fr|co\\.uk)/(exec/obidos|o)/ASIN\\d?/\\w{10}/(ref=nosim/)?([^/?]+)", "i");
    var isbn     = new RegExp("^http://www\\.amazon\\.(com|ca|co\\.jp|de|fr|co\\.uk)/(exec/obidos|o)/ISBN=\\w{10}/(ref=nosim/)?([^/?]+)A", "i");
    var mp       = new RegExp("^http://www\\.amazon\\.(com|ca|co\\.jp|de|fr|co\\.uk)/gp/associates/link-types/marketplace", "i");

    var allLinks = document.getElementsByTagName('a');
    var imp = {};

    var orgUnit = {
        'com'   : 1,
        'ca'    : 15,
        'co.jp' : 9,
        'de'    : 3,
        'fr'    : 8,
        'co.uk' : 2
    };

    var ccmid = {
        'as2' : '9325',
       '-as2' : '9325',
        'am2' : '374921',
       '-am2' : '9325'
    };

    var camp = '211189';
    var timeoutReached = false;

    for (var i=0; i < allLinks.length; i++)
    {
        // Check if it's an Amazon redirect link
        var href = new String(allLinks[i].href);
        var results;
        if (results = href.match(redirect))
        {
            var locale = results[1];
            // Change link code to impression-tracked version
            if (href.match(/link_code=asn/))
            {

                var code = 'as2';
                href = href.replace(/link_code=asn/, 'link_code=' + code);
                href = href.replace(/creative=\d+/, 'creative=' + ccmid[code]);
                href = href.replace(/camp=\d+/, 'camp=' + camp);
                allLinks[i].href = href;
                var tag = href.match(/tag=([^&]+)/)[1];
                imp = amazon_logImpression(imp, locale, tag, code);
            }
            else if (href.match(/link_code=as2/))
            {
                var code = 'as2';
                href = href.replace(/creative=\d+/, 'creative=' + ccmid[code]);
                href = href.replace(/camp=\d+/, 'camp=' + camp);
                allLinks[i].href = href;
                var tag = href.match(/tag=([^&]+)/)[1];
                imp = amazon_logImpression(imp, locale, tag, code);
                imp = amazon_logImpression(imp, locale, tag, '-as2', -1);
            }
            else if (href.match(/link_code=asm/))
            {

                var code = 'am2';
                href = href.replace(/link_code=asm/, 'link_code=' + code);
                href = href.replace(/creative=\d+/, 'creative=' + ccmid[code]);
                href = href.replace(/camp=\d+/, 'camp=' + camp);
                allLinks[i].href = href;
                var tag = href.match(/tag=([^&]+)/)[1];
                imp = amazon_logImpression(imp, locale, tag, code);
            }
            else if (href.match(/link_code=am2/))
            {
                var code = 'am2';
                href = href.replace(/creative=\d+/, 'creative=' + ccmid[code]);
                href = href.replace(/camp=\d+/, 'camp=' + camp);
                allLinks[i].href = href;
                var tag = href.match(/tag=([^&]+)/)[1];
                imp = amazon_logImpression(imp, locale, tag, code);
                imp = amazon_logImpression(imp, locale, tag, '-am2', -1);
            }
            else if (href.match(/link_code=ure/))
            {
                href = href.replace(/link_code=ure/, 'link_code=ur2');
                allLinks[i].href = href;
                var tag = href.match(/tag=([^&]+)/)[1];
                imp = amazon_logImpression(imp, locale, tag, 'ur2');
            }


            else if (!href.match(/link_code=/) && href.match(/tag=([^&]+)/))
            {
                href = href + '&link_code=ur2&camp=' + camp + '&creative=9325';
                allLinks[i].href = href;
                var tag = href.match(/tag=([^&]+)/)[1];
                imp = amazon_logImpression(imp, locale, tag, 'ur2');
            }
        }
        // Check if it's an old-style ASIN link
        else if (results = href.match(asin))
        {
            var locale = results[1];

            var code = 'as2';
            // Replace ASIN handler with redirect
            href = href.replace(/ASIN\d?\/(\w{10})\/(ref=nosim\/)?([^\/\?]+).*/i, 'redirect?tag=$3&creative=' + ccmid[code] + '&camp=' + camp + '&link_code=' + code + '&path=ASIN/$1');
            allLinks[i].href = href;
            var tag = results[4];
            imp = amazon_logImpression(imp, locale, tag, code);
        }
        // Check if it's a really-old-style ISBN link
        else if (results = href.match(isbn))
        {
            var locale = results[1];

            var code = 'as2';
            // Replace ISBN handler with redirect
            href = href.replace(/ISBN=(\w{10})\/(ref=nosim\/)?([^\/\?]+)A.*/, 'redirect?tag=$3&creative=' + ccmid[code] + '&camp=' + camp + '&link_code=' + code + '&path=ASIN/$1');
            allLinks[i].href = href;
            var tag = results[4];
            imp = amazon_logImpression(imp, locale, tag, code);
        }
        // Check if it's an old-style marketplace link
        else if (results = href.match(mp))
        {
            var locale = results[1];

            var code = 'am2';
            // Replace marketplace handler with redirect
            var mpTarget = new RegExp('/gp/associates/link-types/marketplace\\.html\\?asin=(\\w{10})&(amp;)?t=([^/]+)');
            href = href.replace(mpTarget, '/exec/obidos/redirect?tag=$3&creative=' + ccmid[code] + '&camp=' + camp + '&link_code=' + code + '&path=tg/stores/offering/list/-/$1/all/$1');
            var mpTarget = new RegExp('/gp/associates/link-types/marketplace\\.html\\?t=([^&]+)&(amp;)?asin=(\\w{10})');
            href = href.replace(mpTarget, '/exec/obidos/redirect?tag=$1&creative=' + ccmid[code] + '&camp=' + camp + '&link_code=' + code + '&path=tg/stores/offering/list/-/$3/all/$3');
            allLinks[i].href = href;
            var tag = href.match(/tag=([^&]+)/)[1];
            imp = amazon_logImpression(imp, locale, tag, code);
        }


        // Have we gone over our time limit?
        var now = new Date();
        now = now.getTime();
        if (now > (start + timeout))
        {
            timeoutReached = true;
            break;
        }
    }

    var tagID;
    var scripts = document.getElementsByTagName('script');
    for (var i=0; i < scripts.length; i++)
    {
        var source = new String(scripts[i].src);
        var tagIDObj;
        if (tagIDObj = source.match(/link-enhancer.*\?tag=([^&]+)/))
        {
            tagID = tagIDObj[1];
            break;
        }
    }



    // Send data to impression recorder via img tags
    for (var locale in imp)
    {
        var tld = (locale == 'co.jp') ? 'jp' : locale;
        for (var tag in imp[locale])
        {
            // Record the fact that this script was served.
            var tc = 'pv0';
            document.write('<img src="http://www.assoc-amazon.' + tld + '/e/ir' +
                    '?l=' + tc +
                    '&t=' + tag +
                    '&o=' + orgUnit[locale] + '" />');

            for (var code in imp[locale][tag])
            {
                var link_code = new String(code);
                link_code = link_code.replace(/^-/, '');
                document.write('<img src="http://www.assoc-amazon.' + tld + '/e/ir' +
                      '?t=' + tag +
                      '&l=' + link_code +
                      '&o=' + orgUnit[locale] +
                      '&creative=' + ccmid[code] +
                      '&camp=' + camp +
                      '&i=' + imp[locale][tag][code] + '" />');
            }
        }
    }

    if (timeoutReached)
    {
        document.write('<img src="http://www.assoc-amazon.com/e/ir?t=' + tagID + '&l=to0&o=1&i=' + total + '" />');
    }
}

function amazon_logImpression(imp, locale, tag, code, count)
{
    if (!count)
    {
        count = 1;
    }

    if (imp[locale])
    {
        if (imp[locale][tag])
        {
            if (imp[locale][tag][code])
            {
                imp[locale][tag][code] = imp[locale][tag][code] + count;
            }
            else
            {
                imp[locale][tag][code] = count;
            }
        }
        else
        {
            imp[locale][tag] = {};
            imp[locale][tag][code] = count;
        }
    }
    else
    {
        imp[locale] = {};
        imp[locale][tag] = {};
        imp[locale][tag][code] = count;
    }

    return imp;
}
